// middleware/auth.go
package middleware

import (
	"bsm/logger"
	"bsm/models"
	"net/http"
	"strings"

	jwt "github.com/appleboy/gin-jwt/v2"
	"github.com/gin-gonic/gin"
)

// 用户角色常量(已在models/model_user.go中定义)

// GetCurrentUserRoles 从JWT claims获取用户角色列表
func GetCurrentUserRoles(c *gin.Context) []string {
	claims := jwt.ExtractClaims(c)

	// jwt.MapClaims 的处理方式
	if rolesInterface, exists := claims["roles"]; exists {
		switch roles := rolesInterface.(type) {
		case []string:
			return roles
		case []interface{}:
			var roleStrings []string
			for _, role := range roles {
				if roleStr, ok := role.(string); ok {
					roleStrings = append(roleStrings, roleStr)
				}
			}
			return roleStrings
		}
	}
	return []string{}
}

// ==================== 权限检查函数 ====================

// HasRole 检查是否拥有某个角色 (基于claims缓存)
func HasRole(c *gin.Context, roleID string) bool {
	roles := GetCurrentUserRoles(c)
	for _, role := range roles {
		if role == roleID {
			return true
		}
	}
	return false
}

// HasAnyRole 检查是否拥有任意指定角色 (基于claims缓存)
func HasAnyRole(c *gin.Context, targetRoleIDs ...string) bool {
	userRoles := GetCurrentUserRoles(c)
	for _, userRole := range userRoles {
		for _, targetRole := range targetRoleIDs {
			if userRole == targetRole {
				return true
			}
		}
	}
	return false
}

// ==================== 角色权限中间件 ====================

// RoleRequired 通用角色检查中间件 (基于claims缓存，高性能)
func RoleRequired(requiredRoleIDs ...string) gin.HandlerFunc {
	return func(c *gin.Context) {
		if !HasAnyRole(c, requiredRoleIDs...) {
			c.JSON(http.StatusForbidden, gin.H{
				"信息": "权限不足，需要的角色: " + strings.Join(requiredRoleIDs, " 或 "),
			})
			c.Abort()
			return
		}
		c.Next()
	}
}

// AdminRequired 管理员权限检查
func AdminRequired() gin.HandlerFunc {
	logger.Info("check admin")
	return RoleRequired(models.UserRole_Admin)
}

// DesignerRequired 设计师权限检查
func DesignerRequired() gin.HandlerFunc {
	return RoleRequired(models.UserRole_Admin, models.UserRole_Designer)
}

// ReviewerRequired 审核员权限检查
func DesignReviewerRequired() gin.HandlerFunc {
	return RoleRequired(models.UserRole_Admin, models.UserRole_DesignReviewer)
}

// ClientRequired 客户权限检查
func ClientRequired() gin.HandlerFunc {
	return RoleRequired(models.UserRole_Admin, models.UserRole_Client)
}

// ==================== 便捷检查函数 ====================

// IsAdmin 检查当前用户是否是管理员
func IsAdmin(c *gin.Context) bool {
	return HasRole(c, models.UserRole_Admin)
}

// IsDesigner 检查当前用户是否是设计师
func IsDesigner(c *gin.Context) bool {
	return HasAnyRole(c, models.UserRole_Admin, models.UserRole_Designer)
}

// IsReviewer 检查当前用户是否是审核员
func IsReviewer(c *gin.Context) bool {
	return HasAnyRole(c, models.UserRole_Admin, models.UserRole_DesignReviewer)
}

// IsClient 检查当前用户是否是客户
func IsClient(c *gin.Context) bool {
	return HasAnyRole(c, models.UserRole_Admin, models.UserRole_Client)
}

// GetCurrentUserID 从JWT claims获取当前用户ID
func GetCurrentUserID(c *gin.Context) string {
	claims := jwt.ExtractClaims(c)
	if userID, ok := claims["user_id"].(string); ok {
		return userID
	}
	return ""
}

// GetCurrentUserName 从JWT claims获取用户名
func GetCurrentUserName(c *gin.Context) string {
	claims := jwt.ExtractClaims(c)
	if userName, ok := claims["user_name"].(string); ok {
		return userName
	}
	return ""
}

// GetCurrentOrgCode 从JWT claims获取组织代码
func GetCurrentOrgCode(c *gin.Context) string {
	claims := jwt.ExtractClaims(c)
	if orgCode, ok := claims["org_code"].(string); ok {
		return orgCode
	}
	return ""
}
